require 'cgi'
require 'net/http'

require 'weather'
require 'cacheable'

require 'rubygems'
require 'xmpp4r-simple'

class WeatherBot

  attr_reader :weather

  include Cacheable

  def initialize(jid, password, weather_rss, time_to_send, screen_name=nil, logger=nil)
    @jid = jid
    @password = password

    @times_to_send = time_to_send
    @last_sent_to_twitter = Time.local(0)

    @screen_name = screen_name
    @logger = logger
    
    @weather = Weather.new(weather_rss)
    
    log("starting up")
    
  end

  def run
    update_status
    update_twitter_buddy_icon
    send_to_twitter
    reply_to_messages
  end

  private

  def update_status
    log("updating status #{weather.condition}")
    jabber.status(:chat, weather.condition)
    true
  end

  def update_twitter_buddy_icon
    filename = weather.photo
    return if filename.nil? || File.exists?(filename)
    `curl -F \"user[profile_image]=@#{filename}\" -u #{@screen_name}:#{@password} http://twitter.com/account/picture`
    true
  end

  def send_to_twitter
    return unless ready_to_send?
    jabber.deliver("twitter@twitter.com", weather.condition)
    log("deliver #{weather.condition}")
    @last_sent_to_twitter = Time.now.getgm
    true
  end

  def reply_to_messages
    jabber.received_messages.each do |message|
      if message.from.node == 'twitter' || message.from.domain =~ /twitter\.com/
        next unless screen_name_element = message.elements['//screen_name']
        sender = screen_name_element.text

        # don't send to the other weatherbots.
        next if sender.match(/^wx/)
        
        case message.body
        when /nudged you to update/: reply_to_nudge(sender)
        when /\(direct from/:        reply_to_direct(sender, message.body)
        end
      else
        log("msg from unrecognized user")
        # we have a non-twitter user contacting us. hallelujliah.
      end
    end
  end

  def reply_to_nudge(sender)
    log("replying to nudge from #{sender}")
    jabber.deliver("twitter@twitter.com", "d #{sender} #{weather.condition}")
  end

  def reply_to_direct(sender, message)
    reply_to_nudge(sender)
  end

  def ready_to_send?
    now = Time.now.getgm
    #return false if @last_sent_to_twitter > now - 15.minutes
    
    @times_to_send.each do |tts|
      tts = today(tts[0].to_i, tts[1].to_i)
      return true if (@last_sent_to_twitter < tts and now > tts)
    end
    
    false
  end

  def jabber
    begin
      unless @jabber
        log("connecting....")
        @jabber = Jabber::Simple.new(@jid, @password, :chat, "Updating Soon.") 
      end  
    rescue => e
      log("[#{Time.now}] Couldn't connect to Jabber (#{@jid}, #{@password}): #{e}.")
      sleep 60
      retry
    end
    @jabber
  end

  def log(msg)
    msg = "#{@screen_name}: #{msg}"
    
    if @logger
      @logger.info(msg)
    else
      STDERR.puts(msg)
    end
  end
  
  
  def today(hour,min)
      nowz = Time.now.getgm
      return Time.gm(nowz.year, nowz.month, nowz.day, hour, min)
  end

  caches :update_status, :for => 15.minutes
  caches :update_twitter_buddy_icon, :for => 15.minutes
  

end
